package org.backend.utils;

import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
public class JwtUtil {

    // 密钥 (建议使用更强的密钥)
    private static final String SECRET_KEY = "U2x4bmVy";

    // 设置 JWT 过期时间
    private static final long EXPIRATION_TIME = TimeUnit.HOURS.toMillis(24); // 24小时
//    private static final long EXPIRATION_TIME = TimeUnit.MINUTES.toMillis(1);  // 1分钟

    /**
     * 生成JWT token
     *
     * @param claims
     * @return
     */
    public static String generateToken(Map<String, Object> claims) {
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY) // 使用HS256算法和密钥签名
                .addClaims(claims) // 自定义声明
                .setIssuedAt(new Date(System.currentTimeMillis())) // 生成时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // 过期时间
                .compact();
        return jwt;
    }


    public static Claims parseToken(String token) {
        log.info(token);
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }

    public static String getOpenId(String token) {
        Claims claims = JwtUtil.parseToken(token);
        return (String) claims.get("openid");
    }

    public static <T> T setOpenId(T entity, String token) {
        if (token != null) {
            try {
                String openId = getOpenId(token);
                if (openId != null) { // 有找到openid证明是微信端用户，反之网页端
                    // 使用反射来设置openId字段
                    Method setOpenidMethod = entity.getClass().getMethod("setOpenid", String.class);
                    ((Method) setOpenidMethod).invoke(entity, openId);

                    // 解决SQL语句ON DUPLICATE KEY问题，若user_id为空则无法判断重复
                    Method setUserIdMethod = entity.getClass().getMethod("setUserId", Integer.class);
                    setUserIdMethod.invoke(entity, -1);
                }
            } catch (Exception e) {
                log.error("Error setting openId for entity: {}", e.getMessage());
            }
        }
        return entity;
    }


    /**
     * 验证JWT是否过期
     *
     * @param token JWT token
     * @return 是否过期
     */
    public static boolean isTokenExpired(String token) {
        return parseToken(token).getExpiration().before(new Date());
    }

    /**
     * 验证JWT是否有效
     *
     * @param token JWT token
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        return !isTokenExpired(token);
    }

    /**
     * 刷新JWT的过期时间，返回一个新的token
     *
     * @param token 原始的JWT token
     * @return 刷新的JWT token
     */
    public static String refreshToken(String token) {
        Claims claims = parseToken(token);  // 解析原始token
        return generateToken(claims);  // 生成一个新的token
    }
}
